package tools;

import gui.CeroRepositoryClient;
import gui.PackagesJXTable;
import gui.ProgressBarFrame;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.JOptionPane;
import javax.swing.JProgressBar;


import database.DatabaseManager;
import database.Package;
import database.Release;
import database.ReleaseIdentifier;


/**
 * @author aioros
 * install package
 */
public class Installer extends Thread{

	
	/**
	 * Frame which conatins a progress Bar
	 */
	private ProgressBarFrame progressBarFrame;
	
	
	/**
	 * progress Bar
	 */
	private JProgressBar progressBar;
	
	
	public Installer(ProgressBarFrame progressBarFrame){
		
		this.progressBarFrame = progressBarFrame;
		this.progressBar = this.progressBarFrame.getProgressBar();
	}
	
	
	/**
	 * throw installing
	 */
	public void run(){
		
		CeroRepositoryClient.getCeroRepositoryClient().setEnabled(false);
		ReleaseIdentifier currentRls = PackagesJXTable.getPackagesJXTable().getCurrentRelease();
		
		if (currentRls != null){
			
			Package p = DatabaseManager.getDatabaseManager().getLocalDatabase().getPackages().get(currentRls.getPackageID());
			Release r = p.getBranches().get(currentRls.getBranchID()).getReleases().get(currentRls.getReleaseID());
			if (r.getStatus().equals("0")){
				
				String zipName = 	currentRls.getPackageID() + "-" +
									currentRls.getBranchID() + "-" +
									currentRls.getReleaseID() +
									".zip";
				
				// file download
				this.fileDownload(DatabaseManager.DEFAULT_URL_INSTALL + 
						zipName );
				
				// unzip the file
				try {
					
					File zipFile = new File(DatabaseManager.DEFAULT_PATH_INSTALL + zipName);
					ZipTools.unzip(zipFile, DatabaseManager.DEFAULT_PATH_INSTALL);
					zipFile.delete();
					
					
					// save the database and change the release status
					r.setStatus("3");
					DatabaseManager.getDatabaseManager().saveLocalDatabase();
					PackagesJXTable.getPackagesJXTable().initialize();
				} catch (IOException e1) {
					JOptionPane.showMessageDialog(CeroRepositoryClient.getCeroRepositoryClient(),
							"IO Error",
							"Error",
							JOptionPane.ERROR_MESSAGE);
					CeroRepositoryClient.getCeroRepositoryClient().setEnabled(true);
					progressBarFrame.dispose();
				}
			}
		}
		
		CeroRepositoryClient.getCeroRepositoryClient().setEnabled(true);
		progressBarFrame.dispose();
	}
	
	
	
	/**
	 * file download
	 * @param urlFile url file to download
	 */
	private void fileDownload(String urlFile){
		
		URLConnection connection = null;
		InputStream is = null;
		FileOutputStream destinationFile = null;
		
		try { 
			//create the url
	        URL url = new URL(urlFile);

			//create a connection to this url
			connection = url.openConnection( );
	        
			//retrieve file length
			int length = connection.getContentLength();
			this.progressBar.setMaximum(length - 1);
			this.progressBar.setValue(0);
			progressBar.setIndeterminate(false);
			
			//if the file don't exist, a exception has throw
			if(length == -1){
				throw new IOException("Fichier vide");
	       	}

			//retrieve the file stream
			is = new BufferedInputStream(connection.getInputStream());

			//prepare the bits table in order to file data
			byte[] data = new byte[length];

			//current bit
			int currentBit = 0;
			//read position
			int deplacement = 0;
			
			//read data while deplacement < length
			while(deplacement < length){
				currentBit = is.read(data, deplacement, data.length-deplacement);	
				if(currentBit == -1)break;	
				deplacement += currentBit;
				this.progressBar.setValue(deplacement);
			}
			progressBar.setIndeterminate(true);

			//if the end file hasn't reach, a exception has throw
			if(deplacement != length){
				throw new IOException("Le fichier n'a pas été lu en entier (seulement " 
					+ deplacement + " sur " + length + ")");
			}		
		
			//create File Output Stream to the destination file
			destinationFile = new FileOutputStream(DatabaseManager.DEFAULT_PATH_INSTALL +
					urlFile.split("/")[urlFile.split("/").length - 1]); 

			//write the file data in the stream
			destinationFile.write(data);

			//empty the cache and close the stream
			destinationFile.flush();

	      } catch (MalformedURLException e) { 
	    	  JOptionPane.showMessageDialog(CeroRepositoryClient.getCeroRepositoryClient(),
	    			  "Malformed URL : " + urlFile,
						"Error",
						JOptionPane.ERROR_MESSAGE);
	      } catch (IOException e) { 
	    	  JOptionPane.showMessageDialog(CeroRepositoryClient.getCeroRepositoryClient(),
						"IO Error",
						"Error",
						JOptionPane.ERROR_MESSAGE);
	      } finally{
	    	  try {
	    		  is.close();
				  destinationFile.close();
	    	  } catch (IOException e) {
	    		  JOptionPane.showMessageDialog(CeroRepositoryClient.getCeroRepositoryClient(),
	  					"IO Error",
	  					"Error",
	  					JOptionPane.ERROR_MESSAGE);
	    	  }
	      }
	}
}
